﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

using Noris.Schedule.Support;
using Noris.Schedule.Support.Core;
using Noris.Schedule.Support.Data;
using Noris.Schedule.Support.Services;

namespace Noris.Schedule.UI.Components
{
    #region CLASS DRowFilterItem : vizuální reprezentace jedné položky řádkového filtru, potomek System.Windows.Forms.Panel
    /// <summary>
    /// DRowFilter : vizuální reprezentace jedné položky řádkového filtru, potomek System.Windows.Forms.Panel
    /// </summary>
    public class DRowFilterItem : DPanel
    {
        #region KONSTRUKCE A VNITŘNÍ EVENTY
        public DRowFilterItem()
        {
            this.Parent = null;
            this.InitComponents();
        }
        public DRowFilterItem(DColumn parent)
        {
            this.Parent = parent;
            this.InitComponents();
        }
        private void InitComponents()
        {
            this.Size = new Size(150, 16);

            this._FilterConditionBtn = new Button() { Name = "_FilterConditionBtn" };
            this._FilterConditionBtn.Size = new Size(16, 16);
            this._FilterConditionBtn.TabStop = false;
            this._FilterConditionBtn.TabStopChanged += new EventHandler(_TabStopReset);
            this._FilterConditionBtn.Margin = new Padding(0);
            this._FilterConditionBtn.Padding = new Padding(0);
            this._FilterConditionBtn.FlatStyle = FlatStyle.Flat;
            this._FilterConditionBtn.FlatAppearance.BorderSize = 0;
            this._FilterConditionBtn.FlatAppearance.MouseDownBackColor = Color.LightBlue;
            this._FilterConditionBtn.FlatAppearance.MouseOverBackColor = Color.LightCoral;
            this._FilterConditionBtn.Click += new EventHandler(_FilterConditionBtn_Click);
            this._FilterConditionBtn.MouseEnter += new EventHandler(_MouseEnter);
            this._FilterConditionBtn.MouseLeave += new EventHandler(_MouseLeave);

            this._FilterTextBox = new TextBox() { Name = "_FilterTextBox" };
            this._FilterTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this._FilterTextBox.Font = new System.Drawing.Font("Tahoma", 7.8F);
            this._FilterTextBox.GotFocus += new EventHandler(_FilterTextBox_GotFocus);
            this._FilterTextBox.LostFocus += new EventHandler(_FilterTextBox_LostFocus);
            this._FilterTextBox.TabStop = false;
            this._FilterTextBox.TabStopChanged += new EventHandler(_TabStopReset);
            this._FilterTextBox.MouseEnter += new EventHandler(_MouseEnter);
            this._FilterTextBox.MouseLeave += new EventHandler(_MouseLeave);

            this._FilterApplyBtn = new Button() { Name = "_FilterApplyBtn" };
            this._FilterApplyBtn.Size = new Size(12, 16);
            this._FilterApplyBtn.Image = PicLibrary16.Dial_OK_FromFile;
            this._FilterApplyBtn.TabStop = false;
            this._FilterApplyBtn.TabStopChanged += new EventHandler(_TabStopReset);
            this._FilterApplyBtn.Margin = new Padding(0);
            this._FilterApplyBtn.FlatStyle = FlatStyle.Flat;
            this._FilterApplyBtn.FlatAppearance.BorderSize = 0;
            this._FilterApplyBtn.FlatAppearance.MouseDownBackColor = Color.LightBlue;
            this._FilterApplyBtn.FlatAppearance.MouseOverBackColor = Color.LightCoral;
            this._FilterApplyBtn.Click += new EventHandler(_FilterApplyBtn_Click);
            this._FilterApplyBtn.MouseEnter += new EventHandler(_MouseEnter);
            this._FilterApplyBtn.MouseLeave += new EventHandler(_MouseLeave);

            this.ResetFilter();
            this._BackColorFocused = Color.LightGoldenrodYellow;
            this._BackColorEmpty = this._FilterTextBox.BackColor;
            this._BackColorNonEmpty = Color.Salmon;
            this._TextBoxHeight = 14;

            this._ArrangeControls();

            this.BackColor = Color.Transparent;

            this.SizeChanged += new EventHandler(_SizeChanged);

            this.Controls.Add(this._FilterConditionBtn);
            this.Controls.Add(this._FilterTextBox);
            this.Controls.Add(this._FilterApplyBtn);
        }
        /// <summary>
        /// Tato metoda je volána jen jedenkrát, poté kdy je control již umístěný na Formu, a kdy je viditelný.
        /// </summary>
        protected override void OnToolTipInitialize()
        {
            base.OnToolTipInitialize();
            this.SetToolTip(ToolTipIcon.Info, "Řádkový filtr", "Zadejte podmínky řádkového filtru");
            this._FilterConditionBtn.SetToolTip(ToolTipIcon.Info, "Řádkový filtr", "Výběr podmínky filtru pro tento sloupec");
            this._FilterApplyBtn.SetToolTip(ToolTipIcon.Info, "Řádkový filtr", "Aplikuje filtr okamžitě");
            this._FilterTextBox.SetToolTip(ToolTipIcon.Info, "Řádkový filtr", "Zadejte podmínky řádkového filtru");
        }
        void _MouseEnter(object sender, EventArgs e)
        {
            this.OnMouseEnter(e);
        }
        void _MouseLeave(object sender, EventArgs e)
        {
            this.OnMouseLeave(e);
        }
        private Button _FilterConditionBtn;
        private TextBox _FilterTextBox;
        private Button _FilterApplyBtn;
        private string _FilterTextOld;
        private int _TextBoxHeight;
        private Color _BackColorFocused;
        private Color _BackColorEmpty;
        private Color _BackColorNonEmpty;
        /// <summary>
        /// Umístí controly do svého prostoru (typicky po resize)
        /// </summary>
        private void _ArrangeControls()
        {
            this._FilterConditionBtn.Bounds = new Rectangle(0, 0, 16, 16);

            int height = (this._TextBoxHeight > 0 ? this._TextBoxHeight : 18);
            this._FilterTextBox.Bounds = new Rectangle(16, 2, this.Width - 28, height);

            this._FilterApplyBtn.Bounds = new Rectangle(this.Width - 12, 0, 12, 16);
        }
        void _FilterConditionBtn_Click(object sender, EventArgs e)
        {
            this._ShowCondMenu();
        }
        void _FilterApplyBtn_Click(object sender, EventArgs e)
        {
            this.OnFilterChanged();
            this._FilterTextBox.Focus();
        }
        void _TabStopReset(object sender, EventArgs e)
        {
            if (this._FilterTextBox.TabStop)
                this._FilterTextBox.TabStop = false;
        }
        void _FilterTextBox_GotFocus(object sender, EventArgs e)
        {
            this._FilterTextOld = this._FilterTextBox.Text;
            _SetBackColor(true);
            this.OnFilterChangeFocus();
        }
        void _FilterTextBox_LostFocus(object sender, EventArgs e)
        {
            string text = this._FilterTextBox.Text;
            if (!String.Equals(this._FilterTextOld, text))
            {   // Po změně textu volám detekci:
                this._FilterTextDetect(text);
            }
            _SetBackColor(false);
            this.OnFilterChangeFocus();
        }
        /// <summary>
        /// Nastaví barvu pozadí
        /// </summary>
        private void _SetBackColor()
        {
            _SetBackColor(this.Focused);
        }
        /// <summary>
        /// Nastaví barvu pozadí
        /// </summary>
        private void _SetBackColor(bool focused)
        {
            if (focused)
                this._FilterTextBox.BackColor = _BackColorFocused;
            else
            {
                RowFilterItem item = this.RowFilterItem;
                if (item.IsEmpty)
                    this._FilterTextBox.BackColor = _BackColorEmpty;
                else
                    this._FilterTextBox.BackColor = _BackColorNonEmpty;
            }
        }
        /// <summary>
        /// Metoda volaná po změně textu v poli filtru.
        /// Metoda detekuje úvodní znaky a převádí je na podmínku filtru.
        /// </summary>
        /// <param name="text"></param>
        private void _FilterTextDetect(string input)
        {
            string text = input;
            RowFilterConditionType condition = RowFilter.DetectConditionToken(ref text);

            RowFilterItem rfiOld = this.RowFilterItem;

            // Uživatel vepsal podmínku (například text "%mouka"), ta byla detekovaná (condition = RowFilterConditionType.Contain):
            if (condition != RowFilterConditionType.None)
                this._FilterCondition = condition;

            // Zadaný text:
            this._FilterValue = text;

            // Jde o změnu? Pak by se měl vyvolat event:
            RowFilterItem rfiNew = this.RowFilterItem;
            if (!RowFilterItem.Equals(rfiOld, rfiNew))
                this.OnFilterChanged();
        }
        void _SizeChanged(object sender, EventArgs e)
        {
            this._ArrangeControls();
        }
		/// <summary>
		/// Vrátí optimální výšku tohoto objektu podle velikosti fontu
		/// </summary>
		/// <returns></returns>
		private int _GetHeightOptimal()
		{
			float height = this._FilterTextBox.Font.GetHeight();
			return (int)(Math.Ceiling(height)) + 2;
		}
        #endregion
        #region MENU S VÝBĚREM PODMÍNEK FILTRU, DATA POLOŽKY ŘÁDKOVÉHO FILTRU
        /// <summary>
        /// Připraví kontextové menu podmínek řádkového filtru
        /// </summary>
        private void _PrepareCondMenu()
        {
            this.ContextMenuStrip = new ContextMenuStrip();
            this.ContextMenuStrip.Items.Add(_CreateMenuItem(RowFilterConditionType.Equal));
            this.ContextMenuStrip.Items.Add(_CreateMenuItem(RowFilterConditionType.Lower));
            this.ContextMenuStrip.Items.Add(_CreateMenuItem(RowFilterConditionType.LowerOrEqual));
            this.ContextMenuStrip.Items.Add(_CreateMenuItem(RowFilterConditionType.Greater));
            this.ContextMenuStrip.Items.Add(_CreateMenuItem(RowFilterConditionType.GreaterOrEqual));
            this.ContextMenuStrip.Items.Add(_CreateMenuItem(RowFilterConditionType.BeginWith));
            this.ContextMenuStrip.Items.Add(_CreateMenuItem(RowFilterConditionType.Contain));
            this.ContextMenuStrip.Items.Add(_CreateMenuItem(RowFilterConditionType.NonBeginWith));
            this.ContextMenuStrip.Items.Add(_CreateMenuItem(RowFilterConditionType.NonContain));
            this.ContextMenuStrip.Items.Add(_CreateMenuItem(RowFilterConditionType.NonEqual));
			this.ContextMenuStrip.Items.Add(_CreateMenuItem(RowFilterConditionType.Empty));
			this.ContextMenuStrip.Items.Add(_CreateMenuItem(RowFilterConditionType.NonEmpty));

            this.ContextMenuStrip.ItemClicked += new ToolStripItemClickedEventHandler(_ContextMenuStrip_ItemClicked);
        }
        /// <summary>
        /// Vytvoří a vrátí jednu položku menu
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        private ToolStripMenuItem _CreateMenuItem(RowFilterConditionType condition)
        {
            ToolStripMenuItem item = new ToolStripMenuItem();
            item.Text = GetTextForCondition(condition);
            item.Image = GetImageForCondition(condition);
			item.ImageScaling = ToolStripItemImageScaling.None;
            item.Tag = condition;
            return item;
        }
        /// <summary>
        /// Zobrazí menu s podmínkami
        /// </summary>
        private void _ShowCondMenu()
        {
            if (this.ContextMenuStrip == null)
                this._PrepareCondMenu();

            // Podbarvím si řádek, který je aktuálně vybraný:
            RowFilterConditionType condition = this.FilterCondition;
            foreach (ToolStripMenuItem menuItem in this.ContextMenuStrip.Items)
            {
                bool current = (menuItem.Tag is RowFilterConditionType && (RowFilterConditionType)menuItem.Tag == condition);
                menuItem.BackColor = (current ? Color.LightGoldenrodYellow : this.ContextMenuStrip.BackColor);
            }

            this.ContextMenuStrip.Show(this._FilterConditionBtn, new Point(this._FilterConditionBtn.Left - 5, this._FilterConditionBtn.Bottom));
        }
        /// <summary>
        /// Někdo vybral položku s podmínkou filtru
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _ContextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            this.ContextMenuStrip.Hide();

            if (e.ClickedItem.Tag is RowFilterConditionType)
            {
                this.FilterCondition = (RowFilterConditionType)e.ClickedItem.Tag;
            }
            this._FilterTextBox.Focus();
        }
        /// <summary>
        /// Podmínka filtru.
        /// Změna se promítá do ikony před textboxem.
        /// Změna vyvolá event OnFilterChanged.
        /// </summary>
        protected RowFilterConditionType FilterCondition
        {
            get { return this._FilterCondition; }
            set
            {
                RowFilterItem rfiOld = this.RowFilterItem;

                this._FilterCondition = value;
                this._FilterConditionBtn.Image = GetImageForCondition(value);

                RowFilterItem rfiNew = this.RowFilterItem;
                if (!RowFilterItem.Equals(rfiOld, rfiNew))
                    this.OnFilterChanged();
            }
        }
        /// <summary>
        /// Text v textboxu.
        /// Změna vyvolá event OnFilterChanged.
        /// </summary>
        protected string FilterValue
        {
            get { return this._FilterValue; }
            set
            {
                RowFilterItem rfiOld = this.RowFilterItem;

                this._FilterValue = value;

                RowFilterItem rfiNew = this.RowFilterItem;
                if (!RowFilterItem.Equals(rfiOld, rfiNew))
                    this.OnFilterChanged();
            }
        }
        /// <summary>
        /// Aktuální typ podmínky. Zápis hodnoty zajistí aktualizaci Image v buttonu this._FilterConditionBtn.
        /// </summary>
        private RowFilterConditionType _FilterCondition
        {
            get { return __FilterCondition; }
            set
            {
                this.__FilterCondition = value;
                if (this._FilterConditionBtn != null)
                    this._FilterConditionBtn.Image = GetImageForCondition(value);
                if (this._FilterTextBox != null)
                    this._FilterTextBox.SetToolTipText(GetTextForCondition(value));
            }
        }
        /// <summary>
        /// Aktuální text podmínky. Zápis hodnoty zajistí aktualizaci Text v textboxu this._FilterTextBox.
        /// </summary>
        private string _FilterValue
        {
            get { return __FilterValue; }
            set
            {
                this.__FilterValue = value;
                if (this._FilterTextBox != null)
                    this._FilterTextBox.Text = value;
            }
        }
        private RowFilterConditionType __FilterCondition;
        private string __FilterValue;
        #endregion
        #region PROPERTY A VNĚJŠÍ EVENTY A METODY
        /// <summary>
        /// Barva pozadí, když má prvek focus
        /// </summary>
        public Color BackColorFocused
        {
            get { return _BackColorFocused; }
            set { _BackColorFocused = value; _SetBackColor(); }
        }
        /// <summary>
        /// Barva pozadí, když je prvek prázdný
        /// </summary>
        public Color BackColorEmpty
        {
            get { return _BackColorEmpty; }
            set { _BackColorEmpty = value; _SetBackColor(); }
        }
        /// <summary>
        /// Barva pozadí, když je prvek neprázdný
        /// </summary>
        public Color BackColorNonEmpty
        {
            get { return _BackColorNonEmpty; }
            set { _BackColorNonEmpty = value; _SetBackColor(); }
        }
        /// <summary>
        /// Obsahuje true, pokud tento řádkový filtr má nyní focus (bliká kurzor v textboxu)
        /// </summary>
        public bool Focused
        { get { return this._FilterTextBox.Focused; } }
        /// <summary>
        /// Obsahuje vždy aktuální položku RowFilterItem (sestavenou z aktuálních hodnot v controlu).
        /// </summary>
        public RowFilterItem RowFilterItem
        {
            get { return RowFilterItem.Create(this.Parent.Index, this.Parent.RowFilterItemName, this._FilterCondition, this._FilterValue); }
        }
        /// <summary>
        /// Parent = Column, ve kterém bydlím
        /// </summary>
        public DColumn Parent { get; set; }
		/// <summary>
		/// Optimální výška, daná velikostí fontu
		/// </summary>
		public int HeightOptimal { get { return _GetHeightOptimal(); } }
        /// <summary>
        /// Událost, kdy se změnila hodnota filtru (text nebo druh)
        /// </summary>
        public event EventHandler FilterChanged;
        /// <summary>
        /// Invoker eventu FilterChanged
        /// </summary>
        protected virtual void OnFilterChanged()
        {
            if (this.FilterChanged != null)
                this.FilterChanged(this, new EventArgs());
        }
        /// <summary>
        /// Událost, když Textbox dostane Focus
        /// </summary>
        public event EventHandler FilterChangeFocus;
        /// <summary>
        /// Invoker eventu FilterGotFocus
        /// </summary>
        protected virtual void OnFilterChangeFocus()
        {
            if (this.FilterChangeFocus != null)
                this.FilterChangeFocus(this, new EventArgs());
        }
        /// <summary>
        /// Vymaže svoji podmínku = nastaví ji do výchozího stavu.
        /// Volitelně je možno potlačit event FilterChanged.
        /// </summary>
        /// <param name="suppresFilterChangedEvent">true = potlačit event volaný při změně filtru</param>
        internal void Clear(bool suppresFilterChangedEvent)
        {
            RowFilterItem rfiOld = this.RowFilterItem;

            this.ResetFilter();

            // Jde o změnu? Pak by se měl vyvolat event (pokud není potlačen hodnotou suppresFilterChangedEvent):
            RowFilterItem rfiNew = this.RowFilterItem;
            if (!suppresFilterChangedEvent && !RowFilterItem.Equals(rfiOld, rfiNew))
                this.OnFilterChanged();
        }
        /// <summary>
        /// Do filtru vepíše výchozí hodnotu (BeginWith, String.Empty).
        /// Hodnoty se objeví i ve vizuálních objektech (this._FilterTextBox.Text a this._FilterConditionBtn.Image).
        /// Nevyvolá se event OnFilterChanged.
        /// </summary>
        internal void ResetFilter()
        {
            this._FilterCondition = RowFilterConditionType.BeginWith;
            this._FilterValue = String.Empty;
            this._SetBackColor(false);
        }
        #endregion
        #region STATIC SERVIS
        /// <summary>
        /// Vrátí Image pro danou podmínku
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public static Image GetImageForCondition(RowFilterConditionType condition)
        {
            switch (condition)
            {
                case RowFilterConditionType.None:
                    return null;
                case RowFilterConditionType.Equal:
                    return PicLibrary16.CndEq_Cached;
                case RowFilterConditionType.BeginWith:
                    return PicLibrary16.CndSY_Cached;
                case RowFilterConditionType.NonBeginWith:
                    return PicLibrary16.CndSN_Cached;
                case RowFilterConditionType.Contain:
                    return PicLibrary16.CndCY_Cached;
                case RowFilterConditionType.NonContain:
                    return PicLibrary16.CndCN_Cached;
                case RowFilterConditionType.NonEqual:
                    return PicLibrary16.CndQY_Cached;
                case RowFilterConditionType.LowerOrEqual:
                    return PicLibrary16.CndLE_Cached;
                case RowFilterConditionType.Lower:
                    return PicLibrary16.CndLT_Cached;
                case RowFilterConditionType.GreaterOrEqual:
                    return PicLibrary16.CndGE_Cached;
                case RowFilterConditionType.Greater:
                    return PicLibrary16.CndGT_Cached;
                case RowFilterConditionType.Empty:
                    return PicLibrary16.CndEY_Cached;
                case RowFilterConditionType.NonEmpty:
                    return PicLibrary16.CndEN_Cached;
                case RowFilterConditionType.InList:
                    return null;
                case RowFilterConditionType.InRange:
                    return null;
            }
            return null;
        }
        /// <summary>
        /// Vrátí text pro danou podmínku
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public static string GetTextForCondition(RowFilterConditionType condition)
        {
            switch (condition)
            {
                case RowFilterConditionType.None:
                    return "";
                case RowFilterConditionType.Equal:
                    return "Stejné";
                case RowFilterConditionType.BeginWith:
                    return "Začíná na";
                case RowFilterConditionType.NonBeginWith:
                    return "Nezačíná na";
                case RowFilterConditionType.Contain:
                    return "Obsahuje";
                case RowFilterConditionType.NonContain:
                    return "Neobsahuje";
                case RowFilterConditionType.NonEqual:
                    return "Nesouhlasí";
                case RowFilterConditionType.LowerOrEqual:
                    return "Menší než, nebo stejné";
                case RowFilterConditionType.Lower:
                    return "Menší než";
                case RowFilterConditionType.GreaterOrEqual:
                    return "Větší než, nebo stejné";
                case RowFilterConditionType.Greater:
                    return "Větší než";
                case RowFilterConditionType.Empty:
                    return "Je prázdné";
                case RowFilterConditionType.NonEmpty:
                    return "Není prázdné";
                case RowFilterConditionType.InList:
                    return "Je v seznamu";
                case RowFilterConditionType.InRange:
                    return "Je v rozmezí";
            }
            return "";
        }
        #endregion
    }
    #endregion
    #region CLASS DRowFilterClear : panel obsahující jeden button určený pro smazání filtru. Tento panel se zobrazuje v systémovém columnu.
    /// <summary>
    /// DRowFilterClear : panel obsahující jeden button určený pro smazání filtru. Tento panel se zobrazuje v systémovém columnu.
    /// Důvodem této podivné existence je to, že takhle vytvořený panel má korektní barvu BackColor (=transparentní, skrz kterou je vidět vykreslený ColumnHeader).
    /// POkud jsem použil přímo Button na ColumnHeaderu, pak jeho barva BackColor byla opsaná z barvy pozadí ColumnHeaderu, takže blbě prosvítala.
    /// </summary>
    public class DRowFilterClear : DPanel
    {
        #region KONSTRUKCE A VNITŘNÍ EVENTY
        public DRowFilterClear()
        {
            this.Parent = null;
            this.InitComponents();
        }
        public DRowFilterClear(DColumn parent)
        {
            this.Parent = parent;
            this.InitComponents();
        }
        private void InitComponents()
        {
            this.Size = new Size(16, 16);

            this._FilterClearBtn = new Button() { Name = "_FilterConditionBtn" };
            this._FilterClearBtn.Size = new Size(16, 16);
            this._FilterClearBtn.TabStop = false;
            this._FilterClearBtn.TabStopChanged += new EventHandler(_TabStopReset);
            this._FilterClearBtn.Image = PicLibrary16.FiltN_FromFile;
            this._FilterClearBtn.Margin = new Padding(0);
            this._FilterClearBtn.Padding = new Padding(0);
            this._FilterClearBtn.FlatStyle = FlatStyle.Flat;
            this._FilterClearBtn.FlatAppearance.BorderSize = 0;
            this._FilterClearBtn.FlatAppearance.MouseDownBackColor = Color.LightBlue;
            this._FilterClearBtn.FlatAppearance.MouseOverBackColor = Color.LightCoral;
            this._FilterClearBtn.Click += new EventHandler(_FilterClearBtn_Click);
            this._FilterClearBtn.MouseEnter += new EventHandler(_MouseEnter);
            this._FilterClearBtn.MouseLeave += new EventHandler(_MouseLeave);

            this._ArrangeControls();

            this.BackColor = Color.Transparent;

            this.SizeChanged += new EventHandler(_SizeChanged);

            this.Controls.Add(this._FilterClearBtn);
        }
        /// <summary>
        /// Tato metoda je volána jen jedenkrát, poté kdy je control již umístěný na Formu, a kdy je viditelný.
        /// </summary>
        protected override void OnToolTipInitialize()
        {
            base.OnToolTipInitialize();

            this.SetToolTip(ToolTipIcon.Info, "Řádkový filtr", "Smaže zadané hodnoty řádkového filtru");
            this._FilterClearBtn.SetToolTip(ToolTipIcon.Info, "Řádkový filtr", "Smaže zadané hodnoty řádkového filtru");
        }
        private Button _FilterClearBtn;
        void _TabStopReset(object sender, EventArgs e)
        {
            if (this._FilterClearBtn.TabStop)
                this._FilterClearBtn.TabStop = false;
        }
        void _MouseEnter(object sender, EventArgs e)
        {
            this.OnMouseEnter(e);
        }
        void _MouseLeave(object sender, EventArgs e)
        {
            this.OnMouseLeave(e);
        }
        void _FilterClearBtn_Click(object sender, EventArgs e)
        {
            this.OnFilterClear();
        }
        void _SizeChanged(object sender, EventArgs e)
        {
            this._ArrangeControls();
        }

        /// <summary>
        /// Umístí controly do svého prostoru (typicky po resize)
        /// </summary>
        private void _ArrangeControls()
        {
            int x = (this.Width - 16) / 2;
            this._FilterClearBtn.Bounds = new Rectangle(x, 0, 16, 16);
        }
        #endregion
        #region PROPERTY A VNĚJŠÍ EVENTY A METODY
        /// <summary>
        /// Parent = Column, ve kterém bydlím
        /// </summary>
        public DColumn Parent { get; set; }
        /// <summary>
        /// Událost, kdy uživatel kliknul na button, čímž chce vymazat filtr
        /// </summary>
        public event EventHandler FilterClear;
        /// <summary>
        /// Invoker eventu FilterChanged
        /// </summary>
        protected virtual void OnFilterClear()
        {
            if (this.FilterClear != null)
                this.FilterClear(this, new EventArgs());
        }
        #endregion
    }
    #endregion
}
